--[[
@author Aurelien Deharbe

This file is part of Cute-Client.

Cute-Client is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Cute-Client is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with Cute-Client.  If not, see <http://www.gnu.org/licenses/>.
]]

module("cssession", package.seeall)

local socket = require("socket")
local json = require("json")

CSSession = {}
CSSession.__index = CSSession

function CSSession.init()
	local cssession = {}
	setmetatable(cssession, CSSession)
	
	local err, cont, port
	cssession.callbacks = {}
	port = 5001
	cont = true
	while cont do
		cssession.server, err = socket.bind("*", port)
		if not err then
			cont = false
		else
			port = port + 1
		end
	end
	cssession.port = port
	return cssession
end

function CSSession:qs(cmd)
	local ret, err
	cmd = cmd.."\n"
	self.socket:send(cmd)
	ret, err = self.socket:receive()
	result = json.decode(ret)
	return result[table.getn(result)]
end

function CSSession:registerCallback(obj, evt, clb)
	return self:registerTypedCallback(obj, evt, clb, "")
end

function CSSession:registerDataCallback(data, clb)
	return self:registerTypedCallback(data, "qsdatachanged", clb, "")
end

function CSSession:registerTypedCallback(obj, evt, clb, tps)
	local cmd, ret, err, key, value
	cmd = "scripts.subscribe('"..obj
	cmd = cmd.."','"..evt.."','"..tps.."','#me#')\n"
	self.socket:send(cmd)
	ret, err = self.socket:receive()
	ret = json.decode(ret)
	
	for key, value in pairs(ret) do
		self.callbacks[value.."."..evt] = clb
	end
end

function CSSession:mainloop()
	local ret, err, jarray, obj, evt, args, i
	while true do
		ret, err = self.socket:receive()
		if err or not ret then
			break
		end
		jarray = json.decode(ret)
		obj = jarray[1]
		evt = obj.."."..jarray[2]
		if self.callbacks[evt] then
			args = {}
			for i = 3,table.getn(jarray) do
				args[i-2] = jarray[i]
			end
			if args then
				self.callbacks[evt](obj, args)
			else
				self.callbacks[evt](obj)
			end
		end
	end
end

function CSSession:putData(name, value)
	local val, cmd
	val = json.encode(value)
	cmd = "json.loads('"..val.."')"
	cmd = cmd.." -> "..string.sub(name, 2, string.len(name)-1)
	cmd = cmd.."\n"
	self.socket:send(cmd)
	self.socket:receive()
end

function CSSession:getData(name)
	local cmd, ret, err
	cmd = name.."\n"
	self.socket:send(cmd)
	ret, err = self.socket:receive()
	result = json.decode(ret)
	return result[table.getn(result)]
end

function CSSession:getPort()
	return self.port
end

function CSSession:accept()
	local err
	self.socket, err = self.server:accept()
	self.server:close()
end
